package com.cicigodd.brick.plug.system.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cicigodd.brick.plug.common.entity.LoginUser;
import com.cicigodd.brick.plug.common.entity.LoginUserInfo;
import com.cicigodd.brick.plug.common.entity.SimpleUserInfo;
import com.cicigodd.brick.plug.common.enums.YesOrNoEnum;
import com.cicigodd.brick.plug.common.exception.BusinessException;
import com.cicigodd.brick.plug.common.factory.PageFactory;
import com.cicigodd.brick.plug.common.factory.PageResultFactory;
import com.cicigodd.brick.plug.common.response.PageResult;
import com.cicigodd.brick.plug.common.utils.PasswordUtil;
import com.cicigodd.brick.plug.system.auth.api.AuthServiceContext;
import com.cicigodd.brick.plug.system.role.api.SysRoleServiceApi;
import com.cicigodd.brick.plug.system.role.request.SysRoleUserAddRequest;
import com.cicigodd.brick.plug.system.role.service.SysRoleUserService;
import com.cicigodd.brick.plug.system.user.entity.SysUser;
import com.cicigodd.brick.plug.system.user.mapper.SysUserMapper;
import com.cicigodd.brick.plug.system.user.request.*;
import com.cicigodd.brick.plug.system.user.response.SysUserDetailResponse;
import com.cicigodd.brick.plug.system.user.response.SysUserListResponse;
import com.cicigodd.brick.plug.system.user.service.SysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 系统用户管理
 *
 * @author cicigodd
 * @date 2022/09/22 14:42:03
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {


    @Resource
    private SysRoleUserService sysRoleUserService;
    @Resource
    private SysRoleServiceApi sysRoleServiceApi;

    /**
     * 获取个人信息
     *
     * @return
     */
    @Override
    public SimpleUserInfo getUserInfo(Integer userId) {
        SysUser sysUser = this.getById(userId);
        if (ObjectUtil.isEmpty(sysUser)) {
            throw new BusinessException("查询结果不存在");
        }
        SimpleUserInfo simpleUserInfo = new SimpleUserInfo();
        BeanUtil.copyProperties(sysUser, simpleUserInfo);
        // 填充角色信息
        List<String> roles = sysRoleServiceApi.getRolesByUserId(sysUser.getId());
        simpleUserInfo.setRoles(roles);

        // 填充权限信息
        if(sysUser.getSuperAdminFlag().equals("Y")){
            List<String> perms = new ArrayList<>();
            perms.add("*:*:*");
            simpleUserInfo.setPerms(perms);
        }else{
            List<String> perms = sysRoleServiceApi.getPermsByUserId(sysUser.getId());
            simpleUserInfo.setPerms(perms);
        }
        return simpleUserInfo;
    }

    /**
     * 更新密码
     *
     * @param sysUserUpdatePwdRequest
     */
    @Override
    public void updatePassword(SysUserUpdatePwdRequest sysUserUpdatePwdRequest) {
        Integer userId = AuthServiceContext.me().getLoginUser().getUserId();
        SysUser sysUser = this.getById(userId);
        if (ObjectUtil.isEmpty(sysUser)) {
            throw new BusinessException("查询结果不存在");
        }
        boolean weekPassword = PasswordUtil.isWeekPassword(sysUserUpdatePwdRequest.getNewPassword());
        if (weekPassword) {
            throw new BusinessException("检测到您的密码是弱密码，请加强密码复杂度");
        }
        Boolean aBoolean = PasswordUtil.checkPassword(sysUserUpdatePwdRequest.getPassword(), sysUser.getPassword());
        if (aBoolean) {
            sysUser.setPassword(PasswordUtil.encrypt(sysUserUpdatePwdRequest.getNewPassword()));
            this.updateById(sysUser);
        } else {
            throw new BusinessException("密码错误无法修改!");
        }

    }

    /**
     * 重置密码
     *
     * @param sysUserAddRequest
     */
    @Override
    public void resetPwd(SysUserResetRequest sysUserAddRequest) {
        SysUser sysUser = this.getById(sysUserAddRequest.getId());
        if (ObjectUtil.isEmpty(sysUser)) {
            throw new BusinessException("查询结果不存在");
        }
        sysUser.setPassword(PasswordUtil.encrypt("123456"));
        this.updateById(sysUser);
    }

    /**
     * 添加
     *
     * @author cicigodd
     * @date 2022/09/22 14:42:03
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysUserAddRequest sysUserAddRequest) {
        SysUser sysUser = new SysUser();
        BeanUtil.copyProperties(sysUserAddRequest, sysUser);
        boolean weekPassword = PasswordUtil.isWeekPassword(sysUser.getPassword());
        if (weekPassword) {
            throw new BusinessException("检测到您的密码是弱密码，请加强密码复杂度");
        }
        sysUser.setPassword(PasswordUtil.encrypt(sysUser.getPassword()));
        sysUser.setSuperAdminFlag("N");
        this.save(sysUser);
        //保存用户角色关系
        sysUserAddRequest.getRoleIds().forEach(roleId ->{
            SysRoleUserAddRequest sysRoleUserAddRequest = new SysRoleUserAddRequest();
            sysRoleUserAddRequest.setRoleId(roleId);
            sysRoleUserAddRequest.setUserId(sysUser.getId());
            sysRoleUserService.add(sysRoleUserAddRequest);
        });
    }

    @Override
    public Integer addUser(SysUserAddRequest sysUserAddRequest) {
        SysUser sysUser = new SysUser();
        BeanUtil.copyProperties(sysUserAddRequest, sysUser);
        boolean weekPassword = PasswordUtil.isWeekPassword(sysUser.getPassword());
        if (weekPassword) {
            throw new BusinessException("检测到您的密码是弱密码，请加强密码复杂度");
        }
        sysUser.setPassword(PasswordUtil.encrypt(sysUser.getPassword()));
        sysUser.setSuperAdminFlag("N");
        this.save(sysUser);
        //保存用户角色关系
        sysUserAddRequest.getRoleIds().forEach(roleId ->{
            SysRoleUserAddRequest sysRoleUserAddRequest = new SysRoleUserAddRequest();
            sysRoleUserAddRequest.setRoleId(roleId);
            sysRoleUserAddRequest.setUserId(sysUser.getId());
            sysRoleUserService.add(sysRoleUserAddRequest);
        });
        return sysUser.getId();
    }

    /**
     * 删除
     *
     * @author cicigodd
     * @date 2022/09/22 14:42:03
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(SysUserDeleteRequest sysUserDeleteRequest) {
        List<Integer> ids = sysUserDeleteRequest.getIds();
        List<SysUser> sysUsers = this.listByIds(ids);
        boolean bool = sysUsers.stream().anyMatch(item -> item.getSuperAdminFlag().equals(YesOrNoEnum.Y.getCode()));
        if (bool) {
            throw new BusinessException("选项中有超级管理员不能删除");
        }
        this.removeByIds(ids);
    }

    /**
     * 删除
     * @param userId
     */
    @Override
    public void deleteUserById(Integer userId) {
        this.removeById(userId);
    }


    /**
     * 编辑
     *
     * @author cicigodd
     * @date 2022/09/22 14:42:03
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysUserEditRequest sysUserEditRequest) {
        SysUser sysUser = this.getById(sysUserEditRequest.getId());
        if (ObjectUtil.isEmpty(sysUser)) {
            throw new BusinessException("查询结果不存在");
        }
        BeanUtil.copyProperties(sysUserEditRequest, sysUser);
        //如果密码不为空更新密码
        if(ObjectUtil.isNotEmpty(sysUserEditRequest.getPassword())) {
            boolean weekPassword = PasswordUtil.isWeekPassword(sysUser.getPassword());
            if (weekPassword) {
                throw new BusinessException("检测到您的密码是弱密码，请加强密码复杂度");
            }
            sysUser.setPassword(PasswordUtil.encrypt(sysUser.getPassword()));
        }
        this.updateById(sysUser);
        //删除用户绑定的角色
        sysRoleUserService.deleteByUserId(sysUser.getId());
        //保存用户角色关系
        sysUserEditRequest.getRoleIds().forEach(roleId ->{
            SysRoleUserAddRequest sysRoleUserAddRequest = new SysRoleUserAddRequest();
            sysRoleUserAddRequest.setRoleId(roleId);
            sysRoleUserAddRequest.setUserId(sysUser.getId());
            sysRoleUserService.add(sysRoleUserAddRequest);
        });
    }

    @Override
    public void updateUserInfo(SysUserUpdateUserInfoRequest sysUserUpdateUserInfoRequest) {
        SysUser sysUser = this.getById(sysUserUpdateUserInfoRequest.getId());
        if (ObjectUtil.isEmpty(sysUser)) {
            throw new BusinessException("查询结果不存在");
        }
        BeanUtil.copyProperties(sysUserUpdateUserInfoRequest, sysUser);
        this.updateById(sysUser);
    }

    /**
     * 详情
     *
     * @author cicigodd
     * @date 2022/09/22 14:42:03
     */
    @Override
    public SysUserDetailResponse detail(SysUserDetailRequest sysUserDetailRequest) {
        SysUser sysUser = this.getById(sysUserDetailRequest.getId());
        if (ObjectUtil.isEmpty(sysUser)) {
            throw new BusinessException("查询结果不存在");
        }
        SysUserDetailResponse sysUserDetailResponse = new SysUserDetailResponse();
        BeanUtil.copyProperties(sysUser, sysUserDetailResponse);
        return sysUserDetailResponse;
    }

    /**
     * 列表
     *
     * @author cicigodd
     * @date 2022/09/22 14:42:03
     */
    @Override
    public PageResult<SysUserListResponse> list(SysUserListRequest sysUserListRequest) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        String realName = sysUserListRequest.getRealName();
        String nickName = sysUserListRequest.getNickName();
        String account = sysUserListRequest.getAccount();
        String password = sysUserListRequest.getPassword();
        String avatar = sysUserListRequest.getAvatar();
        String birthday = sysUserListRequest.getBirthday();
        String sex = sysUserListRequest.getSex();
        String phone = sysUserListRequest.getPhone();
        String superAdminFlag = sysUserListRequest.getSuperAdminFlag();
        String dealerFlag = sysUserListRequest.getDealerFlag();
        String lastLoginIp = sysUserListRequest.getLastLoginIp();
        Date lastLoginTime = sysUserListRequest.getLastLoginTime();

        String search = sysUserListRequest.getSearch();
        wrapper.and(ObjectUtil.isNotEmpty(search),qwrapper -> qwrapper.like(SysUser::getNickName, search).or().like(SysUser::getPhone, search));

        wrapper.like(ObjectUtil.isNotEmpty(realName), SysUser::getRealName, realName);
        wrapper.like(ObjectUtil.isNotEmpty(nickName), SysUser::getNickName, nickName);
        wrapper.like(ObjectUtil.isNotEmpty(account), SysUser::getAccount, account);
        wrapper.like(ObjectUtil.isNotEmpty(password), SysUser::getPassword, password);
        wrapper.like(ObjectUtil.isNotEmpty(avatar), SysUser::getAvatar, avatar);
        wrapper.eq(ObjectUtil.isNotEmpty(birthday), SysUser::getBirthday, birthday);
        wrapper.eq(ObjectUtil.isNotEmpty(dealerFlag), SysUser::getDealerFlag, dealerFlag);
        wrapper.like(ObjectUtil.isNotEmpty(sex), SysUser::getSex, sex);
        wrapper.like(ObjectUtil.isNotEmpty(phone), SysUser::getPhone, phone);
        wrapper.like(ObjectUtil.isNotEmpty(superAdminFlag), SysUser::getSuperAdminFlag, superAdminFlag);
        wrapper.like(ObjectUtil.isNotEmpty(lastLoginIp), SysUser::getLastLoginIp, lastLoginIp);
        wrapper.eq(ObjectUtil.isNotNull(lastLoginTime), SysUser::getLastLoginTime, lastLoginTime);

        //查询当前经销商下的用户
        LoginUser loginUser = AuthServiceContext.me().getLoginUser();
        if(!loginUser.getSuperAdmin()){
            wrapper.eq(SysUser::getDealerId, loginUser.getUserId());
        }
        IPage<SysUserListResponse> page = this.page(PageFactory.defaultPage(sysUserListRequest.getPageNum(), sysUserListRequest.getPageSize()), wrapper).convert(SysUser -> BeanUtil.copyProperties(SysUser, SysUserListResponse.class));
        return PageResultFactory.createPageResult(page);
    }

    @Override
    public SysUser getUserByAccount(String account) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getAccount, account);
        queryWrapper.ne(SysUser::getDelFlag, YesOrNoEnum.Y.getCode());
        SysUser sysUser = this.getOne(queryWrapper);
        return sysUser;
    }


    @Override
    public LoginUserInfo getUserLoginInfo(String account) {
        // 1. 获取用户和账号信息
        SysUser sysUser = this.getUserByAccount(account);
        // 用户不存在
        if (ObjectUtil.isNull(sysUser)) {
            throw new BusinessException(account + "用户不存在");
        }
        // 创建登录用户对象
        LoginUser loginUser = new LoginUser();

        // 填充用户账号，账号id，管理员类型
        loginUser.setAccount(sysUser.getAccount());
        loginUser.setUserId(sysUser.getId());
        loginUser.setUserType(sysUser.getUserType());
        loginUser.setSuperAdmin(YesOrNoEnum.Y.getCode().equals(sysUser.getSuperAdminFlag()));

        // 填充用户基本信息
        SimpleUserInfo simpleUserInfo = getUserInfo(sysUser.getId());
        loginUser.setSimpleUserInfo(simpleUserInfo);
        loginUser.setLoginTime(new Date());

        //组装返回结果
        LoginUserInfo loginUserInfo = new LoginUserInfo();
        // 设置用户加密的密码和状态
        loginUserInfo.setUserPasswordHexed(sysUser.getPassword());
        loginUserInfo.setUserStatus(sysUser.getStatusFlag());
        loginUserInfo.setLoginUser(loginUser);

        return loginUserInfo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateUserLoginInfo(Integer userId, Date loginTime, String ip) {
        // 根据用户id获取用户信息实体
        LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserLambdaQueryWrapper.eq(SysUser::getId, userId).eq(SysUser::getDelFlag, YesOrNoEnum.N.getCode());
        SysUser sysUser = this.getOne(sysUserLambdaQueryWrapper);

        if (sysUser != null) {
            // 更新用户登录信息
            SysUser user = new SysUser();
            user.setId(sysUser.getId());
            user.setLastLoginIp(ip);
            user.setLastLoginTime(loginTime);
            this.updateById(user);
        }
    }

    /**
     * 获取用户名
     * @param userId
     * @return
     */
    @Override
    public String getUserNameById(Integer userId) {
        SysUser sysUser = this.getById(userId);
        return sysUser.getNickName();
    }

    @Override
    public List<Integer> getRoleIdsByUserId(Integer userId) {
        return sysRoleUserService.getRoleIdsByUserId(userId);
    }
}
